//#define __FORCE_TRACE__
//#define __FORCE_DEBUG__
//#define __FORCE_INFO__
#define THIS_FILE "ia\fn_reinfInfantry.sqf"
#include <tmf_constants.h>
#include <tmf_macros.h>

TRACE_1("Start",_this);
TMFPROFILERSTART;

private ["_men_type","_unit_type","_i","_reinfgrp","_lst","_density","_height","_helper",
		 "_best_spot","_spot","_tries1","_start_pos","_target_radius","_target_pos","_side","_reinf_lower_range","_reinf_higher_range",
		 "_side_variable"];

if !(isServer || (!isDedicated && !hasInterface)) exitWith { ERROR("Reinforcement is server or HC only!"); };

DEFAULT_PARAM(_instance_id,0,TMF_SERVER_INSTANCE_ID);
DEFAULT_PARAM(_target_pos,1,ARR_3(0,0,0));
DEFAULT_PARAM(_side,2,GVAR(SIDE_ENEMY));
DEFAULT_PARAM(_units,3,[]);
DEFAULT_PARAM(_target_radius,5,200);
DEFAULT_PARAM(_start_pos,6,[]);

_range = ["REINF_INFANTRY_RANGE",[800,1100]] call FFUNC(getFrameworkValue);
_side = [_side] call FFUNC(getSide);

if (count _units <= 0) then {
	_side_variable = format["INFANTRY_GROUP_%1",toUpper(str(_side))];
	_units = [_side_variable,[]] call FFUNC(getFrameworkValue);
};

if (_target_radius <= 30) then {
	_target_radius = 50;
};

if (!IS_ARRAY(_start_pos) || {count _start_pos < 2}) then {
	_start_pos = [];
} else {
	if (!(surfaceiswater [(_start_pos select 0), (_start_pos select 1)])) then {
		_helper = "Land_HelipadEmpty_F" createVehicleLocal [(_start_pos select 0), (_start_pos select 1), 0];
		if (!(surfaceIsWater [getPosASL _helper select 0, getPosASL _helper select 1])) then {
			_slope = [position _helper, 5] call XfGetSlope;
			if (_slope > 0.5) then {_start_pos = [];};
		} else {
			_start_pos = [];
		};
		deleteVehicle _helper;
	} else {
		_start_pos = [];
	};
};

if (count _start_pos < 3) then {
	_tries1 = 30;
	// Used to know if a spot is good:
	// 1) The position
	// 2) The height, we want a low point
	// 3) The "density" of the spot, this is the number of player units in the vicinity modulated by their distance.
	_best_spot = [[],2000,100000000];
	_reinf_lower_range = _range select 0;
	_reinf_higher_range = _range select 1;
	_helper = "Land_HelipadEmpty_F" createVehicleLocal [0,0,0];
	while { _tries1 > 0 } do {
		_spot = [_target_pos, _reinf_higher_range, _reinf_lower_range] call FFUNC(getRanPointCircle);
		if (count _spot > 0) then {
			if (count _spot == 3) then {
				TRACE_1("Testing spot", _spot);
				_helper setPos _spot;
				_height = (getPosASL _helper) select 2;
				if ((_height < (_best_spot select 1)) || (_height - (_best_spot select 1)) < 50) then {
					_lst = nearestObjects [_spot, ["Man","Car","Tank","Ship"], 400];
					TRACE_1("Acceptable height",ARR_2(_height,count _lst));
					_density = 0;
					{
						if ((side _x) == GVAR(side_own)) then {
							TRACE_1("Own Side", ARR_2(_x,(isplayer _x)));
							if (isplayer _x) then {
								// If a humen player is present, then we highly increase the density to reject as much as possible those spots
								_density = _density + (10000 / (_x distance _spot));
							} else {
								_density = _density + (2000 / (_x distance _spot));
							};
						};
					} foreach _lst;
					if (_density < (_best_spot select 2)) then {
						// We update the best spot
						_best_spot = [_spot, _height, _density];
						// We lower the tries count to narrow a good spot more quickly
						_tries1 = _tries1 - 1;
						TRACE_1("New best spot",ARR_2(_best_spot,_tries1));
					};
				} else {
					TRACE_1("Unacceptable height", _height);
				};
			};
		};
		_tries1 = _tries1 - 1;
	};
	deleteVehicle _helper;
	_start_pos = _best_spot select 0;
};

if (count _start_pos < 3) exitWith {ERROR_1("Could not find a starting position", _this);};
	
// If we have a road nearby, it's better to start on it to avoid being blocked.
_roads = _start_pos nearRoads 100;
if (count _roads > 0) then {
	_start_pos = getPos (_roads call FFUNC(arrayRandomVal));
};

_reinfgrp = [_instance_id, _units,_side,_start_pos,0] call FFUNC(spawnGroup);
_reinfgrp allowFleeing 0;
_reinfgrp setCombatMode "RED";
_reinfgrp setBehaviour "CARELESS";
_reinfgrp setSpeedMode "FULL";
TRACE_1("Created units",ARR_2(_reinfgrp, units _reinfgrp));

[_reinfgrp, _target_pos,_target_radius] call FFUNC(attack);

TRACE_1("End",_reinfgrp);
TMFPROFILERSTOP;